package com.easysettle.data

import android.util.Log
import com.easysettle.model.CartItem
import com.easysettle.model.Product
import java.io.Serializable
import java.util.concurrent.locks.ReentrantReadWriteLock

/**
 * 购物车数据管理器
 * 负责购物车中商品的添加、删除和数量管理
 */
class ShoppingCart : Serializable {
    // 购物车中的商品项列表
    private val items: MutableList<CartItem> = mutableListOf()
    // 读写锁，确保线程安全
    private val lock = ReentrantReadWriteLock()
    
    companion object {
        // 序列化版本ID
        private const val serialVersionUID: Long = 1L
        // 日志标签
        private const val TAG = "ShoppingCart"
    }

    /**
     * 获取所有购物车项
     */
    fun getAllItems(): List<CartItem> {
        lock.readLock().lock()
        try {
            return items.toList()
        } finally {
            lock.readLock().unlock()
        }
    }

    /**
     * 添加商品到购物车
     */
    fun addProduct(product: Product, quantity: Int = 1): Boolean {
        lock.writeLock().lock()
        try {
            // 检查购物车中是否已存在该商品
            val existingItem = items.find { it.product.id == product.id }
            if (existingItem != null) {
                // 如果已存在，增加数量
                existingItem.quantity += quantity
                Log.d(TAG, "商品数量增加: ${product.name}，数量: ${existingItem.quantity}")
            } else {
                // 如果不存在，添加新的购物车项
                items.add(CartItem(product, quantity))
                Log.d(TAG, "商品添加到购物车: ${product.name}")
            }
            return true
        } catch (e: Exception) {
            Log.e(TAG, "添加商品到购物车失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 从购物车中移除商品
     */
    fun removeProduct(productId: String): Boolean {
        lock.writeLock().lock()
        try {
            val removed = items.removeIf { it.product.id == productId }
            if (removed) {
                Log.d(TAG, "商品从购物车移除: $productId")
            } else {
                Log.w(TAG, "购物车中未找到商品: $productId")
            }
            return removed
        } catch (e: Exception) {
            Log.e(TAG, "从购物车移除商品失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 更新购物车中商品的数量
     */
    fun updateQuantity(productId: String, quantity: Int): Boolean {
        lock.writeLock().lock()
        try {
            val item = items.find { it.product.id == productId }
            if (item != null) {
                if (quantity > 0) {
                    item.quantity = quantity
                    Log.d(TAG, "更新商品数量: ${item.product.name}，数量: $quantity")
                } else {
                    // 如果数量小于等于0，移除该商品
                    items.remove(item)
                    Log.d(TAG, "商品数量为0，从购物车移除: ${item.product.name}")
                }
                return true
            }
            Log.w(TAG, "购物车中未找到商品: $productId")
            return false
        } catch (e: Exception) {
            Log.e(TAG, "更新商品数量失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 增加商品数量
     */
    fun increaseQuantity(productId: String): Boolean {
        lock.writeLock().lock()
        try {
            val item = items.find { it.product.id == productId }
            if (item != null) {
                item.increaseQuantity()
                Log.d(TAG, "商品数量增加: ${item.product.name}，数量: ${item.quantity}")
                return true
            }
            Log.w(TAG, "购物车中未找到商品: $productId")
            return false
        } catch (e: Exception) {
            Log.e(TAG, "增加商品数量失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 减少商品数量
     */
    fun decreaseQuantity(productId: String): Boolean {
        lock.writeLock().lock()
        try {
            val item = items.find { it.product.id == productId }
            if (item != null) {
                if (item.quantity > 1) {
                    item.decreaseQuantity()
                    Log.d(TAG, "商品数量减少: ${item.product.name}，数量: ${item.quantity}")
                    return true
                } else {
                    // 如果数量为1，减少后变为0，移除该商品
                    items.remove(item)
                    Log.d(TAG, "商品数量为0，从购物车移除: ${item.product.name}")
                    return true
                }
            }
            Log.w(TAG, "购物车中未找到商品: $productId")
            return false
        } catch (e: Exception) {
            Log.e(TAG, "减少商品数量失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 清空购物车
     */
    fun clearCart(): Boolean {
        lock.writeLock().lock()
        try {
            items.clear()
            Log.d(TAG, "购物车已清空")
            return true
        } catch (e: Exception) {
            Log.e(TAG, "清空购物车失败", e)
            return false
        } finally {
            lock.writeLock().unlock()
        }
    }

    /**
     * 获取购物车中商品的总数量
     */
    fun getTotalItemCount(): Int {
        lock.readLock().lock()
        try {
            return items.sumOf { it.quantity }
        } finally {
            lock.readLock().unlock()
        }
    }

    /**
     * 获取购物车中不同商品的种类数
     */
    fun getUniqueItemCount(): Int {
        lock.readLock().lock()
        try {
            return items.size
        } finally {
            lock.readLock().unlock()
        }
    }

    /**
     * 获取购物车的总金额
     */
    fun getTotalAmount(): Double {
        lock.readLock().lock()
        try {
            return items.sumOf { it.getSubtotal() }
        } finally {
            lock.readLock().unlock()
        }
    }

    /**
     * 检查购物车是否为空
     */
    fun isEmpty(): Boolean {
        lock.readLock().lock()
        try {
            return items.isEmpty()
        } finally {
            lock.readLock().unlock()
        }
    }

    /**
     * 获取格式化的总金额
     */
    fun getFormattedTotalAmount(): String {
        return String.format("%.2f", getTotalAmount())
    }

    override fun toString(): String {
        return "ShoppingCart(items=$items)"
    }
}